package com.sudo.service.admin.service.impl;

import com.sudo.common.utils.LocalDateTimeUtil;
import com.sudo.dao.admin.entity.SysUserBehavior;
import com.sudo.dao.admin.entity.SysUserLoginRecord;
import com.sudo.dao.admin.entity.SysUserStsDay;
import com.sudo.dao.admin.mapper.SysUserBehaviorMapper;
import com.sudo.dao.admin.mapper.SysUserLoginRecordMapper;
import com.sudo.dao.admin.mapper.SysUserStsDayMapper;
import com.sudo.dao.admin.model.vo.StsBehaviorVO;
import com.sudo.service.admin.service.AdminBaseService;
import com.sudo.service.admin.service.SysUserStsDayService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class SysUserStsDayServiceImpl extends AdminBaseService implements SysUserStsDayService {

    @Resource
    private SysUserBehaviorMapper sysUserBehaviorMapper;

    @Resource
    private SysUserLoginRecordMapper sysUserLoginRecordMapper;

    @Resource
    private SysUserStsDayMapper sysUserStsDayMapper;

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void stsUserBehaviorByDay(LocalDate localDate) {

        Example deleteExample = new Example(SysUserStsDay.class);
        Example.Criteria criteria = deleteExample.createCriteria();
        criteria.andEqualTo("date", localDate);
        sysUserStsDayMapper.deleteByExample(deleteExample);

        String date2Str = LocalDateTimeUtil.convertLocateDate2Str(localDate, LocalDateTimeUtil.yyyy_MM_dd);
        SysUserStsDay sysUserStsDay = new SysUserStsDay();
        // 某天的活跃度（操作数）
        Example userBehaviorExample = new Example(SysUserBehavior.class);
        Example.Criteria userBehaviorCriteria = userBehaviorExample.createCriteria();
        userBehaviorCriteria.andLike("operTime", date2Str+"%");
        int numBehavior = sysUserBehaviorMapper.selectCountByExample(userBehaviorExample);
        sysUserStsDay.setNumBehavior(numBehavior);

        // 某天的登录人次
        Example userLoginNotExample = new Example(SysUserLoginRecord.class);
        Example.Criteria userLoginNotCriteria = userLoginNotExample.createCriteria();
        userLoginNotCriteria.andLike("loginTime",date2Str+"%");
        int loginNot = sysUserLoginRecordMapper.selectCountByExample(userLoginNotExample);
        sysUserStsDay.setLoginNot(loginNot);

        // 某天的登录人数（distinct）
        // selectCountByExample userLoginNopExample.setDistinct(true) 不生效, 只在 selectByExample 生效
        int loginNop = sysUserLoginRecordMapper.selectUserNopCountByDay(date2Str,date2Str);
        sysUserStsDay.setLoginNop(loginNop);

        LocalDateTime createTime = LocalDateTime.now();
        sysUserStsDay.setCreateTime(createTime);
        sysUserStsDay.setDate(localDate);

        sysUserStsDayMapper.insertSelective(sysUserStsDay);
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public SysUserStsDay getUserStsDay(LocalDate localDate) {
        Example example = new Example(SysUserStsDay.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("date",localDate);
        SysUserStsDay sysUserStsDay = sysUserStsDayMapper.selectOneByExample(example);
        if (sysUserStsDay == null) {
            sysUserStsDay = new SysUserStsDay(localDate);
        }
        return sysUserStsDay;
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysUserStsDay> getSysUserStsDayList(LocalDate startLocalDate,LocalDate endLocalDate){
        Example example = new Example(SysUserStsDay.class);
        example.orderBy("date").asc();
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThanOrEqualTo("date",endLocalDate);
        criteria.andGreaterThanOrEqualTo("date",startLocalDate);
        return sysUserStsDayMapper.selectByExample(example);
    }

    @Override
    public List<StsBehaviorVO> getStsBehavior(List<LocalDate> localDateList, List<SysUserStsDay> sysUserStsDayList) {
        List<StsBehaviorVO> stsBehaviorVOList = new ArrayList<>();
        for (LocalDate localDate : localDateList) {
            StsBehaviorVO stsBehaviorVO = new StsBehaviorVO();
            stsBehaviorVO.setDate(localDate);
            for (SysUserStsDay sysUserStsDay : sysUserStsDayList) {
                if (sysUserStsDay.getDate().compareTo(localDate) == 0){
                    BeanUtils.copyProperties(sysUserStsDay,stsBehaviorVO);
                    break;
                }
            }
            stsBehaviorVOList.add(stsBehaviorVO);
        }
        return stsBehaviorVOList;
    }
}
